/**
 * 图片加载控制 Hook
 * 限制同时加载的图片数量，避免网络拥堵
 */

import { useEffect, useRef, useState } from 'react';

interface ImageLoaderOptions {
  /** 最大并发加载数量 */
  maxConcurrent?: number;
  /** 加载超时时间（毫秒） */
  timeout?: number;
}

interface ImageLoadTask {
  url: string;
  resolve: (url: string) => void;
  reject: (error: Error) => void;
}

class ImageLoadQueue {
  private queue: ImageLoadTask[] = [];
  private loading = 0;
  private maxConcurrent: number;
  private timeout: number;

  constructor(maxConcurrent = 3, timeout = 10000) {
    this.maxConcurrent = maxConcurrent;
    this.timeout = timeout;
  }

  add(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
      this.queue.push({ url, resolve, reject });
      this.process();
    });
  }

  private process() {
    while (this.loading < this.maxConcurrent && this.queue.length > 0) {
      const task = this.queue.shift();
      if (!task) break;

      this.loading++;
      this.loadImage(task);
    }
  }

  private loadImage(task: ImageLoadTask) {
    const { url, resolve, reject } = task;
    const img = new Image();
    let timeoutId: NodeJS.Timeout;

    const cleanup = () => {
      this.loading--;
      clearTimeout(timeoutId);
      this.process();
    };

    img.onload = () => {
      cleanup();
      resolve(url);
    };

    img.onerror = () => {
      cleanup();
      reject(new Error(`Failed to load image: ${url}`));
    };

    // 超时处理
    timeoutId = setTimeout(() => {
      cleanup();
      reject(new Error(`Image load timeout: ${url}`));
    }, this.timeout);

    img.src = url;
  }
}

// 全局队列实例
let globalQueue: ImageLoadQueue | null = null;

/**
 * 使用图片加载器
 */
export function useImageLoader(options: ImageLoaderOptions = {}) {
  const { maxConcurrent = 3, timeout = 10000 } = options;

  // 初始化全局队列
  useEffect(() => {
    if (!globalQueue) {
      globalQueue = new ImageLoadQueue(maxConcurrent, timeout);
    }
  }, [maxConcurrent, timeout]);

  const loadImage = (url: string): Promise<string> => {
    if (!globalQueue) {
      globalQueue = new ImageLoadQueue(maxConcurrent, timeout);
    }
    return globalQueue.add(url);
  };

  const loadImages = (urls: string[]): Promise<string[]> => {
    return Promise.all(urls.map((url) => loadImage(url)));
  };

  return { loadImage, loadImages };
}

/**
 * 受控的图片组件 Hook
 * 自动使用加载队列
 */
export function useControlledImage(
  url: string | undefined,
  options?: ImageLoaderOptions,
) {
  const [loadedUrl, setLoadedUrl] = useState<string | undefined>(undefined);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);
  const { loadImage } = useImageLoader(options);
  const abortRef = useRef(false);

  useEffect(() => {
    if (!url) {
      setLoadedUrl(undefined);
      return;
    }

    abortRef.current = false;
    setLoading(true);
    setError(null);

    loadImage(url)
      .then((loadedUrl) => {
        if (!abortRef.current) {
          setLoadedUrl(loadedUrl);
          setLoading(false);
        }
      })
      .catch((err) => {
        if (!abortRef.current) {
          setError(err);
          setLoading(false);
        }
      });

    return () => {
      abortRef.current = true;
    };
  }, [url, loadImage]);

  return { url: loadedUrl, loading, error };
}
